extends layout

block append style
  link(rel="stylesheet" href="/docs/css/flexcpc.css")
  script(type="text/javascript" src="/docs/js/native.js")

block content
  :markdown
    # Transactions in Mongoose

    [Transactions](https://www.mongodb.com/transactions) are new in MongoDB
    4.0 and Mongoose 5.2.0. Transactions let you execute multiple operations
    in isolation and potentially undo all the operations if one of them fails.
    This guide will get you started using transactions with Mongoose.

    ## Your First Transaction

    [MongoDB currently only supports transactions on replica sets](https://docs.mongodb.com/manual/replication/#transactions),
    not standalone servers. To run a
    [local replica set for development](http://thecodebarbarian.com/introducing-run-rs-zero-config-mongodb-runner.html)
    on macOS, Linux or Windows, use npm to install
    [run-rs](https://www.npmjs.com/package/run-rs) globally and run
    `run-rs --version 4.0.0`. Run-rs will download MongoDB 4.0.0 for you.

    To use transactions with Mongoose, you should use Mongoose `>= 5.2.0`. To
    check your current version of Mongoose, run `npm list | grep "mongoose"`
    or check the [`mongoose.version` property](http://mongoosejs.com/docs/api.html#mongoose_Mongoose-version).

    Transactions are built on [MongoDB sessions](https://docs.mongodb.com/manual/reference/server-sessions/).
    To start a transaction, you first need to call [`startSession()`](/docs/api.html#startsession_startSession)
    and then call the session's `startTransaction()` function. To execute an
    operation in a transaction, you need to pass the `session` as an option.

    ```javascript
    [require:transactions.*basic example]
    ```

    ## Aborting a Transaction

    The most important feature of transactions is the ability to roll back _all_
    operations in the transaction using the [`abortTransaction()` function](https://docs.mongodb.com/manual/reference/method/Session.abortTransaction/).

    Think about [modeling a bank account in Mongoose](https://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html#transactions-with-mongoose).
    To transfer money from account `A` to account `B`, you would decrement
    `A`'s balance and increment `B`'s balance. However, if `A` only has a balance
    of $5 and you try to transfer $10, you want to abort the transaction and undo
    incrementing `B`'s balance.

    ```javascript
    [require:transactions.*abort]
    ```

    ## With Mongoose Documents and `save()`

    If you get a [Mongoose document](/docs/documents.html) from [`findOne()`](/docs/api.html#findone_findOne)
    or [`find()`](/docs/api.html#find_find) using a session, the document will
    keep a reference to the session and use that session for [`save()`](/docs/api.html#document_Document-save).

    To get/set the session associated with a given document, use [`doc.$session()`](/docs/api.html#document_Document-$session).

    ```javascript
    [require:transactions.*save]
    ```

    ## With the Aggregation Framework

    The `Model.aggregate()` function also supports transactions. Mongoose
    aggregations have a [`session()` helper](/docs/api.html#aggregate_Aggregate-session)
    that sets the [`session` option](/docs/api.html#aggregate_Aggregate-option).
    Below is an example of executing an aggregation within a transaction.

    ```javascript
    [require:transactions.*aggregate]
    ```

block append layout
  script.
    _native.init("CK7DT53U", {
      targetClass: 'native-js',
      display: 'flex',
      visibleClass: 'native-show'
    });

  div(class="native-js").
    <div class="native-sponsor">Sponsored by #native_company# — Learn More</div>
    <a href="#native_link#" class="native-flex">
      <style>
      .native-js {
        background: linear-gradient(-30deg, #native_bg_color#E5, #native_bg_color#E5 45%, #native_bg_color# 45%) #fff;
      }

      .native-details,
      .native-sponsor,
      .native-bsa {
        color: #native_color# !important;
      }

      .native-details:hover {
        color: #native_color_hover# !important;
      }

      .native-cta {
        color: #native_cta_color#;
        background-color: #native_cta_bg_color#;
      }

      .native-cta:hover {
        color: #native_cta_color_hover;
        background-color: #native_cta_bg_color_hover#;
      }
      </style>
      <div class="native-main">
        <img class="native-img" src="#native_logo#">
        <div class="native-details">
          <span class="native-company">#native_title#</span>
          <span class="native-desc">#native_desc#</span>
        </div>
      </div>
      <span class="native-cta">#native_cta#</span>
    </a>
